package handler

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"

	"vod-service/config" // 替换为实际项目路径

	"github.com/gin-gonic/gin"
	"github.com/volcengine/volc-sdk-golang/service/vod/models/business"
	"github.com/volcengine/volc-sdk-golang/service/vod/models/request"
	"github.com/volcengine/volc-sdk-golang/service/vod/upload/functions"
	"github.com/volcengine/volc-sdk-golang/service/vod/upload/model"
)

// 上传结果数据结构
type UploadResult struct {
	RequestID string `json:"request_id"` // 火山引擎请求ID
	Vid       string `json:"vid"`        // 视频ID
	FileName  string `json:"file_name"`  // 文件名
}

// 1. 文件路径上传请求参数
type UploadMediaByFileRequest struct {
	SpaceName        string   `json:"space_name" binding:"required"` // 空间名称
	FilePath         string   `json:"file_path" binding:"required"`  // 本地文件路径
	CallbackArgs     string   `json:"callback_args,omitempty"`       // 回调参数
	Title            string   `json:"title,omitempty"`               // 视频标题
	Tags             string   `json:"tags,omitempty"`                // 标签（逗号分隔）
	Description      string   `json:"description,omitempty"`         // 描述
	TemplateIds      []string `json:"template_ids,omitempty"`        // 转码模板ID
	ImpTemplateIds   []string `json:"imp_template_ids,omitempty"`    // 智能处理模板ID
	ClassificationId int64    `json:"classification_id,omitempty"`   // 分类ID
}

// 2. URL上传请求参数
type UploadMediaByURLRequest struct {
	SpaceName        string            `json:"space_name" binding:"required"` // 空间名称
	SourceURL        string            `json:"source_url" binding:"required"` // 源视频URL
	CallbackArgs     string            `json:"callback_args,omitempty"`       // 回调参数
	FileName         string            `json:"file_name,omitempty"`           // 文件名
	FileExtension    string            `json:"file_extension,omitempty"`      // 文件后缀（如.mp4）
	CustomURLHeaders map[string]string `json:"custom_url_headers,omitempty"`  // 自定义请求头
}

// 3. 流上传请求参数（通过form-data传递文件）
type UploadMediaByStreamRequest struct {
	SpaceName        string   `form:"space_name" binding:"required"` // 空间名称
	FileName         string   `form:"file_name" binding:"required"`  // 文件名
	CallbackArgs     string   `form:"callback_args,omitempty"`       // 回调参数
	Title            string   `form:"title,omitempty"`               // 视频标题
	Tags             string   `form:"tags,omitempty"`                // 标签
	Description      string   `form:"description,omitempty"`         // 描述
	TemplateIds      []string `form:"template_ids,omitempty"`        // 转码模板ID
	ImpTemplateIds   []string `form:"imp_template_ids,omitempty"`    // 智能处理模板ID
	ClassificationId int64    `form:"classification_id,omitempty"`   // 分类ID
}

// 构建通用的VOD上传功能配置（截图、元数据、工作流等）
func buildVodFunctions(title, tags, description, format string, classificationId int64, templateIds, impTemplateIds []string) (string, error) {
	// 截图功能
	snapShotFunc := functions.SnapshotFunc(business.VodUploadFunctionInput{
		SnapshotTime: 1.3,
	})

	// 元数据提取功能
	getMetaFunc := functions.GetMetaFunc()

	// 工作流功能（转码+智能处理）
	var templates []*business.VodUploadTemplate
	if len(templateIds) > 0 {
		templates = append(templates, &business.VodUploadTemplate{
			TemplateIds:  templateIds,
			TemplateType: "transcode",
		})
	}
	if len(impTemplateIds) > 0 {
		templates = append(templates, &business.VodUploadTemplate{
			TemplateIds:  impTemplateIds,
			TemplateType: "imp",
		})
	}
	startWorkFlowFunc := functions.StartWorkflowFunc(business.VodUploadFunctionInput{
		Templates: templates,
	})

	// 选项信息功能
	optionFunc := functions.AddOptionInfoFunc(business.VodUploadFunctionInput{
		Title:            title,
		Tags:             tags,
		Description:      description,
		Format:           format,
		ClassificationId: int32(classificationId),
		IsHlsIndexOnly:   false,
	})

	// 组合所有功能并序列化为JSON
	vodFunctions := []business.VodUploadFunction{snapShotFunc, getMetaFunc, startWorkFlowFunc, optionFunc}
	fbts, err := json.Marshal(vodFunctions)
	if err != nil {
		return "", fmt.Errorf("序列化功能配置失败: %v", err)
	}
	return string(fbts), nil
}

// 1. 文件路径上传接口
func UploadMediaByFileHandler(c *gin.Context) {
	var req UploadMediaByFileRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, config.Response{
			Code:    http.StatusBadRequest,
			Message: "参数错误: " + err.Error(),
		})
		return
	}

	// 校验文件是否存在
	if _, err := os.Stat(req.FilePath); os.IsNotExist(err) {
		c.JSON(http.StatusBadRequest, config.Response{
			Code:    http.StatusBadRequest,
			Message: "文件不存在: " + req.FilePath,
		})
		return
	}

	// 构建功能配置
	functionsStr, err := buildVodFunctions(
		req.Title, req.Tags, req.Description, "MP4",
		req.ClassificationId, req.TemplateIds, req.ImpTemplateIds,
	)
	if err != nil {
		c.JSON(http.StatusInternalServerError, config.Response{
			Code:    http.StatusInternalServerError,
			Message: "构建功能配置失败: " + err.Error(),
		})
		return
	}

	// 构建上传请求
	uploadReq := &request.VodUploadMediaRequest{
		SpaceName:        req.SpaceName,
		FilePath:         req.FilePath,
		CallbackArgs:     req.CallbackArgs,
		Functions:        functionsStr,
		FileExtension:    ".mp4",
		VodUploadSource:  "upload",
		ParallelNum:      2,
		UploadHostPrefer: "",
	}

	// 执行上传
	resp, _, err := config.GetVodInstance().UploadMediaWithCallback(uploadReq)
	if err != nil {
		c.JSON(http.StatusInternalServerError, config.Response{
			Code:    http.StatusInternalServerError,
			Message: "上传失败: " + err.Error(),
		})
		return
	}

	// 响应结果
	c.JSON(http.StatusOK, config.Response{
		Code:    http.StatusOK,
		Message: "上传成功",
		Data: UploadResult{
			RequestID: resp.GetResponseMetadata().GetRequestId(),
			Vid:       resp.GetResult().GetData().GetVid(),
			FileName:  resp.GetResult().GetData().GetSourceInfo().GetFileName(),
		},
	})
}

// 2. URL上传接口
func UploadMediaByURLHandler(c *gin.Context) {
	var req UploadMediaByURLRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, config.Response{
			Code:    http.StatusBadRequest,
			Message: "参数错误: " + err.Error(),
		})
		return
	}

	// 构建URL上传配置
	urlSets := []*business.VodUrlUploadURLSet{
		{
			SourceUrl:        req.SourceURL,
			CallbackArgs:     req.CallbackArgs,
			FileName:         req.FileName,
			FileExtension:    req.FileExtension,
			CustomURLHeaders: req.CustomURLHeaders,
		},
	}

	// 构建上传请求
	uploadReq := &request.VodUrlUploadRequest{
		SpaceName: req.SpaceName,
		URLSets:   urlSets,
	}

	// 执行上传
	resp, _, err := config.GetVodInstance().UploadMediaByUrl(uploadReq)
	if err != nil {
		c.JSON(http.StatusInternalServerError, config.Response{
			Code:    http.StatusInternalServerError,
			Message: "上传失败: " + err.Error(),
		})
		return
	}

	// 解析结果（URL上传返回结果结构与文件上传不同）
	c.JSON(http.StatusOK, config.Response{
		Code:    http.StatusOK,
		Message: "上传成功",
		Data: UploadResult{
			RequestID: resp.GetResponseMetadata().GetRequestId(),
			Vid:       req.SourceURL,
			FileName:  req.FileName,
		},
	})
}

// 3. 流上传接口
func UploadMediaByStreamHandler(c *gin.Context) {
	var req UploadMediaByStreamRequest
	if err := c.ShouldBind(&req); err != nil { // 注意：流上传用ShouldBind（支持form-data）
		c.JSON(http.StatusBadRequest, config.Response{
			Code:    http.StatusBadRequest,
			Message: "参数错误: " + err.Error(),
		})
		return
	}

	// 获取上传的文件流
	file, err := c.FormFile("file")
	if err != nil {
		c.JSON(http.StatusBadRequest, config.Response{
			Code:    http.StatusBadRequest,
			Message: "获取文件流失败: " + err.Error(),
		})
		return
	}

	// 打开文件
	src, err := file.Open()
	if err != nil {
		c.JSON(http.StatusInternalServerError, config.Response{
			Code:    http.StatusInternalServerError,
			Message: "打开文件失败: " + err.Error(),
		})
		return
	}
	defer src.Close()

	// 读取文件内容
	content, err := io.ReadAll(src)
	if err != nil {
		c.JSON(http.StatusInternalServerError, config.Response{
			Code:    http.StatusInternalServerError,
			Message: "读取文件内容失败: " + err.Error(),
		})
		return
	}

	// 构建功能配置
	functionsStr, err := buildVodFunctions(
		req.Title, req.Tags, req.Description, "MP4",
		req.ClassificationId, req.TemplateIds, req.ImpTemplateIds,
	)
	if err != nil {
		c.JSON(http.StatusInternalServerError, config.Response{
			Code:    http.StatusInternalServerError,
			Message: "构建功能配置失败: " + err.Error(),
		})
		return
	}

	// 构建流上传请求
	uploadReq := &model.VodStreamUploadRequest{
		SpaceName:        req.SpaceName,
		Content:          bytes.NewReader(content),
		Size:             int64(len(content)),
		ChunkSize:        0, // 默认20M分片
		CallbackArgs:     req.CallbackArgs,
		Functions:        functionsStr,
		FileName:         req.FileName,
		FileExtension:    ".mp4",
		VodUploadSource:  "upload",
		UploadHostPrefer: "",
	}

	// 执行上传
	resp, _, err := config.GetVodInstance().UploadMediaStreamWithCallback(uploadReq)
	if err != nil {
		c.JSON(http.StatusInternalServerError, config.Response{
			Code:    http.StatusInternalServerError,
			Message: "流上传失败: " + err.Error(),
		})
		return
	}

	// 响应结果
	c.JSON(http.StatusOK, config.Response{
		Code:    http.StatusOK,
		Message: "上传成功",
		Data: UploadResult{
			RequestID: resp.GetResponseMetadata().GetRequestId(),
			Vid:       resp.GetResult().GetData().GetVid(),
			FileName:  resp.GetResult().GetData().GetSourceInfo().GetFileName(),
		},
	})
}
func RegisterMediaRoutes(r *gin.Engine) {
	uploadMediaGroup := r.Group("/api/v1/upload/media")
	{
		uploadMediaGroup.GET("/stream", func(c *gin.Context) {
			// 向模板传递变量（键值对形式）
			c.HTML(http.StatusOK, "index.html", gin.H{})
		})
		uploadMediaGroup.POST("/file", UploadMediaByFileHandler)     // 文件路径上传
		uploadMediaGroup.POST("/url", UploadMediaByURLHandler)       // URL上传
		uploadMediaGroup.POST("/stream", UploadMediaByStreamHandler) // 流上传
	}
}
